

#include "Stdafx.h"
#include <windows.h>
#include <stdio.h>

#define ALLEGRO_NO_MAGIC_MAIN
#include "allegro5/allegro.h"
#include "allegro5/joystick.h"
#include "allegro5/events.h"
#include "../AdditionalLibrary/Allegro/include/allegro5/joystick.h"
#include "../AdditionalLibrary/Allegro/include/allegro5/events.h"

#define ALLEGRO_INITIALIZE_SUCCESS 1
#define ALLEGRO_INITIALIZE_ERROR 2
#define ALLEGRO_INITIALIZE_JOYSTICK_ERROR 3
#define ALLEGRO_INITIALIZE_EVENT_QUEUE_ERROR 4
#define ALLEGRO_INITIALIZE_TIMER_ERROR 5

#define STUB

struct JoyStruct
{
    int stick;
    int axis;
    float pos;
    int button;
    int type;
};

//static ALLEGRO_JOYSTICK *joystick = NULL;
//static ALLEGRO_EVENT_QUEUE *event_queue = NULL;
//static bool isInitialized = false;


#ifdef STUB // for debug reasons

extern "C" __declspec(dllexport) void Update(JoyStruct *pJoystick)
{
    static int counter = 0;
    counter++;
    pJoystick->axis = pJoystick->button = pJoystick->pos = pJoystick->stick = pJoystick->type = counter;
    return;
}

int procesAttach()
{
    return NO_ERROR;
}

int procesDetach()
{
    return NO_ERROR;
}


#else

extern "C" __declspec(dllexport) void Update(JoyStruct *pJoystick)
{
    static ALLEGRO_JOYSTICK *joystick = NULL;
    static ALLEGRO_EVENT_QUEUE *event_queue = NULL;
    static bool isInitialized = false;

    if(isInitialized == false)
    {
        if(!al_init())
        {
            fprintf(stderr, "failed to init allegro!\n");
            return;
        }

        if(!al_install_joystick())
        {
            fprintf(stderr, "failed to init joystick!\n");
            return;
        }

        al_reconfigure_joysticks();
        joystick=al_get_joystick(al_get_num_joysticks()-1);

        if(!joystick)
        {
            fprintf(stderr, "failed to create joystick!\n");
            return;
        }

        event_queue = al_create_event_queue();
        if(!event_queue)
        {
            fprintf(stderr, "failed to create event_queue!\n");
            return;
        }
        al_register_event_source(event_queue, al_get_joystick_event_source());

        if(event_queue == NULL)
        {
            return;
        }

        isInitialized = true;
    }
    else
    {
        //if(event_queue != NULL)
        //{
            ALLEGRO_EVENT ev;

            al_wait_for_event(event_queue, &ev);

            if(ev.type == ALLEGRO_EVENT_JOYSTICK_AXIS ||
                ev.type == ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN ||
                ev.type == ALLEGRO_EVENT_JOYSTICK_BUTTON_UP)
            {
                pJoystick->axis = ev.joystick.axis;
                pJoystick->button = ev.joystick.button;
                pJoystick->pos = ev.joystick.pos;
                pJoystick->stick = ev.joystick.stick;
                pJoystick->type = ev.joystick.type;
            }
        //}
        //else
        //{
        //    static int counter = 0;
        //    counter++;
        //    //pJoystick->axis = pJoystick->button = pJoystick->pos = pJoystick->stick = pJoystick->type = counter;
        //}
    }
}

int procesAttach()
{
    //if(!al_init())
    //{
    //    fprintf(stderr, "failed to init allegro!\n");
    //    return ALLEGRO_INITIALIZE_ERROR;
    //}

    //if(!al_install_joystick())
    //{
    //    fprintf(stderr, "failed to init joystick!\n");
    //    return ALLEGRO_INITIALIZE_JOYSTICK_ERROR;
    //}

    //al_reconfigure_joysticks();
    //joystick=al_get_joystick(al_get_num_joysticks()-1);

    //if(!joystick)
    //{
    //    fprintf(stderr, "failed to create joystick!\n");
    //    return ALLEGRO_INITIALIZE_JOYSTICK_ERROR;
    //}

    //event_queue = al_create_event_queue();
    //if(!event_queue)
    //{
    //    fprintf(stderr, "failed to create event_queue!\n");
    //    return ALLEGRO_INITIALIZE_EVENT_QUEUE_ERROR;
    //}
    //al_register_event_source(event_queue, al_get_joystick_event_source());

    //if(event_queue == NULL)
    //{
    //    return ALLEGRO_INITIALIZE_EVENT_QUEUE_ERROR;
    //}

    //isInitialized = true;
    return ALLEGRO_INITIALIZE_SUCCESS;
}

int procesDetach()
{
    //al_destroy_event_queue(event_queue);
    //isInitialized = false;
    return NO_ERROR;
}

#endif


int threadAttach()
{
    return -2;
}

int threadDetach()
{
    return -3;
}


int __cdecl DllMain(_In_ void * _HDllHandle, _In_ unsigned _Reason, _In_opt_ void * _Reserved)
{
    int result = -1;
    switch (_Reason)
    {
    case DLL_PROCESS_ATTACH:
        {
            procesAttach();
            //if(isInitialized == false)
            //{
            //    result = procesAttach();
            //}
        }
        break;
    case DLL_THREAD_ATTACH:
        {
            threadAttach();
        }
        break;
    case DLL_THREAD_DETACH:
        {
            threadDetach();
        }
        break;
    case DLL_PROCESS_DETACH:
        {
            procesDetach();
            //if(isInitialized == true)
            //{
            //    procesDetach();
            //}
        }
        break;
    default:
        break;
    }

    return TRUE;
}

